package com.liqi.web.controller.device;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.liqi.common.annotation.Log;
import com.liqi.common.constant.UserConstants;
import com.liqi.common.core.controller.BaseController;
import com.liqi.common.core.domain.AjaxResult;
import com.liqi.common.core.domain.R;
import com.liqi.common.core.page.TableDataInfo;
import com.liqi.common.enums.BusinessType;
import com.liqi.common.utils.DateUtils;

import com.liqi.common.utils.StringUtils;
import com.liqi.common.utils.excel.ExcelUtils;
import com.liqi.common.utils.poi.ExcelUtil;
import com.liqi.common.utils.uuid.GenerateCodeUtils;
import com.liqi.deployment.domain.DvDeployment;
import com.liqi.device.domain.*;
import com.liqi.deployment.service.IDvDeploymentService;
import com.liqi.device.domain.dto.DvModuleExcel;
import com.liqi.device.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import java.util.*;



/**
 * 设备Controller
 *
 * @author zhongping
 * @date 2022-02-14
 */
@Api(tags = "设备管理")
@RestController
@RequestMapping("/device/info")
public class DvDeviceController extends BaseController
{
    @Autowired
    private IDvDeviceService dvDeviceService;
  @Autowired
    private IDvBrandService dvBrandService;

    @Autowired
    private IDvDeviceModuleService dvDeviceModuleService;

    @Autowired
    private IDvModuleService dvModuleService;
    @Autowired
    private IDvDriveService dvDriveService;

    @Autowired
    private IDvDeploymentService dvDeployDeviceManagerService;

    /**
     * 获取所有设备型号
     */
    /*@PreAuthorize("@ss.hasPermi('device:info:getname')")*/

    @GetMapping("/getname")
    public TableDataInfo getname()
    {
        startPage();
        List<String> list = dvDeviceService.selectDvNameList();
        return getDataTable(list);
    }

      /**
     * 查询设备列表
     */
      @ApiOperation("查询设备列表")
    @PreAuthorize("@ss.hasPermi('device:info:list')")
    @GetMapping("/list")
    public TableDataInfo list(DvDevice dvDevice)
    {
        startPage();
        List<DvDevice> list = dvDeviceService.selectDvDeviceList(dvDevice);
        return getDataTable(list);
    }



    /**
     * 获取设备详细信息
     */
    @PreAuthorize("@ss.hasPermi('device:info:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return AjaxResult.success(dvDeviceService.selectDvDeviceById(id));
    }

    /**
     * 新增设备
     */
    @ApiOperation("新增设备")
    @PreAuthorize("@ss.hasPermi('device:info:add')")
    @Log(title = "设备", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody DvDevice dvDevice)
    {
        dvDevice.setCode(GenerateCodeUtils.getSequnce());

        if (UserConstants.NOT_UNIQUE.equals(dvDeviceService.checkCodeUnique(dvDevice)))
        {
            return AjaxResult.error("新增设备" + dvDevice.getName() + "'失败，编码已存在");
        }
        dvDevice.setCreateBy(getUsername());
        dvDevice.setCreateTime(DateUtils.getNowDate());
        dvDevice.setCreateUserId(getUserId().toString());
        dvDevice.setDeptId(getDeptId().toString());
        dvDevice.setUpdateBy(getUsername());
        dvDevice.setUpdateTime(DateUtils.getNowDate());
        return toAjax(dvDeviceService.insertDvDevice(dvDevice));
    }

    /**
     * 修改设备
     */
    @ApiOperation("修改设备")
    @PreAuthorize("@ss.hasPermi('device:info:edit')")
    @Log(title = "设备", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody DvDevice dvDevice)
    {
    	if (UserConstants.NOT_UNIQUE.equals(dvDeviceService.checkCodeUnique(dvDevice)))
        {
            return AjaxResult.error("修改设备" + dvDevice.getName() + "'失败，编码已存在");
        }
        dvDevice.setDeptId(getDeptId().toString());
        dvDevice.setUpdateBy(getUsername());
        dvDevice.setUpdateTime(DateUtils.getNowDate());
        return toAjax(dvDeviceService.updateDvDevice(dvDevice));
    }

    /**
     * 删除设备
     */
    @ApiOperation("删除设备")
    @PreAuthorize("@ss.hasPermi('device:info:remove')")
    @Log(title = "设备", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        List<DvDevice> dvDevices = dvDeviceService.selectDvDeviceListByIds(ids); //根据ID集查询设备
        String[] deviceCodes = new String[1000];
        for (int i = 0; i < dvDevices.size(); i++) {
            String deviceCode = dvDevices.get(i).getCode();
            deviceCodes[i]=deviceCode;
        }
        List<DvDeployment> dvDeployment = dvDeployDeviceManagerService.selectDvDeviceListByDeviceCodes(deviceCodes); //根据设备名称查询设备投放管理信息
        if(dvDeployment.size()!=0){
            for (int i = 0; i < dvDeployment.size(); i++) {
                DvDevice dvDevice = dvDeviceService.selectDvDeviceByDeviceId(dvDeployment.get(i).getDeptId()); 
                dvDeployment.get(i).setDeleteDeviceName(dvDevice.getName()); // 设备名称（设备型号）
                dvDeployment.get(i).setDeleteDeviceCode(dvDevice.getCode()); // 系统自编型号编码
            }
            return AjaxResult.error("设备被正在被投放中，需要先将设备进行解绑", dvDeployment);
        }
        int i = 0;
        for (DvDevice dvDevice : dvDevices) {
            dvDevice.setUpdateBy(getUsername());
            dvDevice.setUpdateTime(DateUtils.getNowDate());
            dvDevice.setStatus(1);
            i = dvDeviceService.updateDvDevice(dvDevice);
        }
        return toAjax(i);
    }


//    @ApiOperation("导入excel")
//    @PostMapping("/import")
//    public R importUser(@RequestPart("file") MultipartFile file) throws Exception {
//
//
//
//        List<DvDeviceExcel> DvDeviceExcel = ExcelUtils.readMultipartFile(file, DvDeviceExcel.class);
//        String message ;
//        if(DvDeviceExcel.size()==0){
//            return  R.fail("上传的文件错误","操作失败");
//        }
//        message=   dvDeviceService.importDevice(DvDeviceExcel);
//        if(StringUtils.isBlank(message)){
//            message="上传成功！";
//        }
//        return R.ok(message);
//    }
    /**
     * 导出设备列表
     */
    @ApiOperation("导出设备")
    @PreAuthorize("@ss.hasPermi('device:info:export')")
    @Log(title = "设备", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, DvDevice dvDevice)
    {


            // 第 1 个 Sheet 页
            List<List<Object>> sheet1 = new ArrayList<>();
            List<Object> sheet1Head = new ArrayList<>();
            sheet1Head.add("设备编码");
            sheet1Head.add("设备名称");
            sheet1Head.add("设备型号");
            sheet1Head.add("BOM编码");
            sheet1Head.add("设备规格");
            sheet1Head.add("品牌编码");
            sheet1Head.add("品牌名称");

        sheet1.add(sheet1Head);

            // 第 2 个 Sheet 页
            List<List<Object>> sheet2 = new ArrayList<>();
            List<Object> sheet2Head = new ArrayList<>();
            sheet2Head.add("设备编码");
            sheet2Head.add("设备名称");
            sheet2Head.add("模块编码");
            sheet2Head.add("模块名称");
            sheet2Head.add("模块型号");
            sheet2Head.add("规格");
            sheet2Head.add("品牌编码");
            sheet2Head.add("品牌名称");
            sheet2Head.add("驱动编码");
            sheet2Head.add("驱动名称");
            sheet2Head.add("插件库名称");
            sheet2.add(sheet2Head);

            // 第 3个 Sheet 页
            List<List<Object>> sheet3 = new ArrayList<>();
            List<Object> sheet3Head = new ArrayList<>();
            sheet3Head.add("设备编码");
            sheet3Head.add("设备名称");
            sheet3Head.add("驱动编码");
            sheet3Head.add("驱动名称");
            sheet3Head.add("插件库名称");
            sheet3.add(sheet3Head);

            if(dvDevice.getExportBlank()!=1) {
                List<DvDevice> list = dvDeviceService.selectDvDeviceList(dvDevice);
                List<DvModuleExcel> models = new ArrayList<>();
                for (DvDevice device : list) {
                    List<Object> row = new ArrayList<>();
                    row.add(device.getCode());
                    row.add(device.getName());
                    row.add(device.getModel());
                    row.add(device.getBomCode());
                    row.add(device.getSpec());
                    row.add(device.getBrandCode());
                    row.add(device.getBrandName());
                    sheet1.add(row);
                    if(device.getBrandCode()!=null&&device.getBrandName()!=null) {
                        DvBrand brand = dvBrandService.selectDvBrandByCode(device.getBrandCode());
                        if (brand == null) {
                            brand = new DvBrand();
                            brand.setName(dvDevice.getBrandName());
                            brand.setCode(dvDevice.getBrandCode());
                            brand.setDeptId(getDeptId().toString());
                            brand.setCreateUserId(getUserId().toString());
                            dvBrandService.insertDvBrand(brand);
                        }
                    }
                    for (DvModule dvModule : device.getModules()) {
                        DvModuleExcel dvModuleExcel = new DvModuleExcel();
                        BeanUtils.copyProperties(dvModule, dvModuleExcel);
                        dvModuleExcel.setDeviceCode(device.getCode());
                        dvModuleExcel.setDeviceName(device.getName());
                        models.add(dvModuleExcel);
                    }
                }
                for (DvModuleExcel dvModule : models) {
                    List<Object> row = new ArrayList<>();
                    row.add(dvModule.getDeviceCode());
                    row.add(dvModule.getDeviceName());
                    row.add(dvModule.getCode());
                    row.add(dvModule.getName());
                    row.add(dvModule.getModel());
                    row.add(dvModule.getSpec());
                    row.add(dvModule.getBrandCode());
                    row.add(dvModule.getBrandName());
                    row.add(dvModule.getDriveCode());
                    row.add(dvModule.getDriveName());
                    row.add(dvModule.getAdapterName());
                    sheet2.add(row);

                }
                for (DvModuleExcel dvModule : models) {
                    String driveCode = dvModule.getDriveCode();
                    if (StringUtils.isNotBlank(driveCode)) {
                        DvDrive dvDrive = dvDriveService.selectDvDriveByDriveCode(driveCode);
                        if (dvDrive != null) {
                            List<Object> row = new ArrayList<>();
                            row.add(dvModule.getDeviceCode());
                            row.add(dvModule.getDeviceName());
                            row.add(dvDrive.getDriveCode());
                            row.add(dvDrive.getDriveName());
                            row.add(dvDrive.getAdapterName());
                            sheet3.add(row);
                        }
                    }

                }
            }
            // 将两个 Sheet 页添加到集合中
            Map<String, List<List<Object>>> sheets = new LinkedHashMap<>();
            sheets.put("设备", sheet1);
            sheets.put("模块", sheet2);
            sheets.put("驱动", sheet3);
            // 导出数据
            ExcelUtils.exportManySheet(response, "设备", sheets);
    }
    @ApiOperation("导入设备")
    @PostMapping("/import")
    public R upload(@RequestPart("file") MultipartFile file) throws Exception {
        StringBuilder sb=new StringBuilder();
        Map<String, JSONArray> map = ExcelUtils.readFileManySheet(file);
        if(map.size()!=3){
            return R.ok("传入的非模板文件,请下载模板文件在进行导入");
        }
        map.forEach((key, value) -> {
            if("设备".equals(key)&&"模块".equals(key)&&"驱动".equals(key)){
                sb.append("传入的非模板文件,请下载模板文件在进行导入");
            }
           else if("设备".equals(key)){
                for(Object array:value) {
                    String json = array.toString();
                    JSONObject jsonObject = JSONObject.parseObject(json);
                    String code = (String) jsonObject.get("设备编码");
                    String name = (String) jsonObject.get("设备名称");
                    String model = (String) jsonObject.get("设备型号");
                    String bomCode = (String) jsonObject.get("BOM编码");
                    String spec = (String) jsonObject.get("设备规格");
                    String brandName = (String) jsonObject.get("品牌名称");
                    String brandCode = (String) jsonObject.get("品牌编码");
                    Integer rowNum = (Integer) jsonObject.get("rowNum");
                    DvDevice dvDevice = dvDeviceService.selectDvDeviceByCode(code);
                    boolean b = ExcelUtils.checkStringIsNull(code, name, model, bomCode, spec, brandName,brandCode);
                    if (b == false) {
                        sb.append("设备页里的第" + rowNum + "行：有值未填");
                        sb.append(";<br/>");
                    } else {
                        if (dvDevice == null) {
                            dvDevice = new DvDevice();
                            dvDevice.setCode(code);
                            dvDevice.setName(name);
                            dvDevice.setModel(model);
                            dvDevice.setBomCode(bomCode);
                            dvDevice.setSpec(spec);
                            dvDevice.setBrandName(brandName);
                            dvDevice.setBomCode(brandCode);
                        dvDevice.setDeptId(getDeptId().toString());
                        dvDevice.setCreateUserId(getUserId().toString());
                            dvDevice.setStatus(0);

                                dvDevice.setBrandName(brandName);
                                dvDevice.setBrandCode(brandCode);
                            DvBrand dvBrand = dvBrandService.selectDvBrandByName(brandName);

                            if (dvBrand == null) {
                                dvBrand=new DvBrand();
                                dvBrand.setCode(brandCode);
                                dvBrand.setName(brandName);
                                dvBrand.setDeptId(getDeptId().toString());
                                dvBrand.setCreateUserId(getUserId().toString());
                                dvBrandService.insertDvBrand(dvBrand);
                            }
                        dvDevice.setCreateBy(getUserId().toString());
                            dvDevice.setCreateTime(new Date());
                            dvDeviceService.insertDvDevice(dvDevice);
                        }
                    }
                }
            }
            else if("模块".equals(key)){
                for(Object array:value){
                    String json = array.toString();
                    JSONObject jsonObject = JSONObject.parseObject(json);
                    String deviceCode = (String) jsonObject.get("设备编码");
                    String deviceName = (String) jsonObject.get("设备名称");
                    String moduleName= (String) jsonObject.get("模块名称");
                    String moduleCode= (String) jsonObject.get("模块编码");
                    String model = (String) jsonObject.get("模块型号");
                    String spec = (String) jsonObject.get("规格");
                    String brandCode = (String) jsonObject.get("品牌编码");
                    String brandName = (String) jsonObject.get("品牌名称");
                    String driveCode = (String) jsonObject.get("驱动编码");
                    String driveName = (String) jsonObject.get("驱动名称");
                    String adapterName = (String) jsonObject.get("插件库名称");
                    Integer rowNum = (Integer) jsonObject.get("rowNum");


                    DvDevice dvDevice = dvDeviceService.selectDvDeviceByCode(deviceCode);


                    boolean b = ExcelUtils.checkStringIsNull( deviceCode, deviceName,moduleName,moduleCode,model,spec,brandCode,brandName,driveCode,driveName,adapterName);
                    if(b==false){
                        sb.append("模块页里的第" + rowNum + "行：有值未填");
                        sb.append(";<br/>");

                    }else {
                    if(dvDevice!=null) {
                        DvDeviceModule DvDeviceModule = dvDeviceModuleService.selectDvDeviceModuleByModuleCodeAndDeviceCode(moduleCode, deviceCode);
                        if (DvDeviceModule == null) {
                            DvDeviceModule deviceModule = new DvDeviceModule();
                            deviceModule.setDeviceCode(deviceCode);
                            deviceModule.setModuleCode(moduleCode);
                            deviceModule.setModuleName(moduleName);
                            dvDeviceModuleService.insertDvDeviceModule(deviceModule);
                        }
                        DvModule dvModule = new DvModule();
                        dvModule.setCode(moduleCode);


                        if (dvModuleService.selectModuleBycode(dvModule.getCode()) == null) {
                            dvModule.setName(moduleName);
                            dvModule.setModel(model);
                            dvModule.setSpec(spec);
                            dvModule.setBrandCode(brandCode);
                            dvModule.setBrandName(brandName);
                            dvModule.setDriveCode(driveCode);
                            dvModule.setDriveName(driveName);
                            dvModule.setAdapterName(adapterName);
                            dvModule.setDeptId(getDeptId().toString());
                            dvModule.setCreateUserId(getUserId().toString());
                            dvModuleService.insertDvModule(dvModule);
                        }
                        DvBrand dvBrand = dvBrandService.selectDvBrandByName(brandName);
                        if (dvBrand == null) {
                            dvBrand=new DvBrand();
                            dvBrand.setCode(brandCode);
                            dvBrand.setName(brandName);
                            dvBrand.setDeptId(getDeptId().toString());
                            dvBrand.setCreateUserId(getUserId().toString());
                            dvBrandService.insertDvBrand(dvBrand);
                        }
                    }
                        DvDrive dvDrive = dvDriveService.selectDvDriveByAdapterName(adapterName);
                        if (dvDrive == null) {
                            dvDrive=new DvDrive();
                            dvDrive.setAdapterName(adapterName);
                            dvDrive.setDriveName(driveName);
                            dvDrive.setDriveCode(driveCode);
                            dvDrive.setDeptId(getDeptId().toString());
                            dvDrive.setCreateUserId(getUserId().toString());
                            dvDriveService.insertDvDrive(dvDrive);
                        }

                    }
                }


            }
           else if("驱动".equals(key)){

                    for(Object array:value) {
                        String json = array.toString();
                        JSONObject jsonObject = JSONObject.parseObject(json);
                        String driveCode = (String) jsonObject.get("驱动编码");
                        String adapterName = (String) jsonObject.get("插件库名称");
                        String driveName = (String) jsonObject.get("驱动名称");
                        Integer rowNum = (Integer) jsonObject.get("rowNum");
                        boolean b = ExcelUtils.checkStringIsNull(driveCode, driveName, adapterName);
                        if (b == false) {
                            sb.append("驱动页里的第" + rowNum + "行：有值未填");
                            sb.append(";<br/>");
                        } else {
                            DvDrive dvDrive = dvDriveService.selectDvDriveByDriveCode(driveCode);
                            if (dvDrive == null) {
                                dvDrive = new DvDrive();

                                dvDrive.setAdapterName(adapterName);
                                dvDrive.setDriveCode(driveCode);
                                dvDrive.setDriveName(driveName);
                                dvDrive.setDeptId(getDeptId().toString());
                                dvDrive.setCreateUserId(getUserId().toString());
                                dvDriveService.insertDvDrive(dvDrive);
                            }
                        }
                    }
            }


        });
        if(StringUtils.isBlank(sb.toString())){
            sb.append("上传成功");
        }
        if (sb.length() > 0 && sb.charAt(sb.length() - 1) == ',') {
            sb.deleteCharAt(sb.length() -1 );
        }


        return R.ok(sb.toString());
    }


}
